#include "stdio.h"
#include "stdarg.h"
#include "string.h"
#include "stdbool.h"

#define INT_MASK	'i'
#define UINT_MASK	'u'
#define STR_MASK	's'

static int mIntPrint(char* buf, int value)
{
	char vBuff[20];
	char *pBuff = vBuff;
	int len = 0, i = 0;
	
	bool neg = value < 0;
	
	if (neg)
	{
		value = -1 * value;
	}
	
	do {
		*pBuff++ = '0' + value % 10;
		value = value / 10;
		len ++;
	} while (value);
	
	if (neg)
	{
		*pBuff++ = '-';
		len ++;
	}
	
	for (i=0; i<len; i++)
	{
		buf[i] = vBuff[len - i - 1];
	}
	
	return len;
}

static int mUintPrint(char* buf, unsigned int value)
{
	char vBuff[20];
	char *pBuff = vBuff;
	int len = 0, i = 0;
	
	do {
		*pBuff++ = '0' + value % 10;
		value = value / 10;
		len ++;
	} while (value);
	
	for (i=0; i<len; i++)
	{
		buf[i] = vBuff[len - i - 1];
	}
	
	return len;
}

static int mStrPrint(char* buf, char* value)
{
	int len = strlen(value);
	
	strncpy(buf, value, len);
	
	return len;
}

void mPrintf(const char* format, ...)
{
	char buf[1024];
	char *pBuff = buf;
	va_list ap ;
    va_start(ap, format);

	int iValue = 0;
	unsigned int uValue = 0;
	char* sVaule = NULL;

	while (*format != '\0')
	{
		// format mask
		if (*format == '%')
		{
			format++;
			switch(*format++)
			{
				case INT_MASK:
				iValue = va_arg(ap,int);
				pBuff += mIntPrint(pBuff, iValue);
				break;
				case UINT_MASK:
				iValue = va_arg(ap,int);
				pBuff += mUintPrint(pBuff, iValue);
				break;
				case STR_MASK:
				sVaule = va_arg(ap,char*);
				pBuff += mStrPrint(pBuff, sVaule);
				break;
			}
		}
		else
		{
			*pBuff++ = *format++;
		}
	}
	
	*pBuff++ = '\0';
	
	va_end(ap);
	
	fprintf(stdout, buf);
}

/*
int main(void)
{
	mPrintf("test %s %i %u\n", "1111", -1024, 2353); 
	return 0;
}
*/